package com.xuecheng.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xuecheng.base.exception.XueChengPlusException;
import com.xuecheng.base.model.PageResult;
import com.xuecheng.content.model.po.CoursePublish;
import com.xuecheng.learning.feignclient.ContentServiceClient;
import com.xuecheng.learning.mapper.XcChooseCourseMapper;
import com.xuecheng.learning.mapper.XcCourseTablesMapper;
import com.xuecheng.learning.model.dto.MyCourseTableParams;
import com.xuecheng.learning.model.dto.XcChooseCourseDto;
import com.xuecheng.learning.model.dto.XcCourseTablesDto;
import com.xuecheng.learning.model.po.XcChooseCourse;
import com.xuecheng.learning.model.po.XcCourseTables;
import com.xuecheng.service.MyCourseTablesService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

@Slf4j
@Service
public class MyCourseTablesServiceImpl implements MyCourseTablesService {
    @Autowired
    private ContentServiceClient contentServiceClient;
    @Autowired
    private XcChooseCourseMapper xcChooseCourseMapper;
    @Autowired
    private XcCourseTablesMapper xcCourseTablesMapper;

    @Override
    @Transactional
    //这个就是按着选课流程图实现的代码
    public XcChooseCourseDto addChooseCourse(String userId, Long courseId) {
        //远程查询课程发布表获取课程的收费规则
        CoursePublish coursepublish = contentServiceClient.getCoursepublish(courseId);
        XcChooseCourse xcChooseCourse =  new XcChooseCourse();
        String charge = coursepublish.getCharge();
        if(charge.equals("201000")){
            //如果是免费课程则添加到选课记录表XcChooseCourse
           xcChooseCourse = addFreeCoruse(userId, coursepublish);
            //如果是免费课程则添加到我的课程表XcCourseTables
            XcCourseTables xcCourseTables = addCourseTabls(xcChooseCourse);
        }else{
            // 如果是收费课程则添加到选课记录表XcChooseCourse
            xcChooseCourse = addChargeCoruse(userId, coursepublish);
        }
        //获取学习的资格 xcCourseTablesDto是课程表
        XcCourseTablesDto xcCourseTablesDto = getLearningStatus(userId, courseId);
        String learnStatus = xcCourseTablesDto.getLearnStatus();

        XcChooseCourseDto xcChooseCourseDto = new XcChooseCourseDto();
        BeanUtils.copyProperties(xcChooseCourse,xcChooseCourseDto);
        xcChooseCourseDto.setLearnStatus(learnStatus);
        //返回选课记录选课记录 然后在前端根据选课记录在支付订单服务生成商品的订单 因为学习中心服务没有调用订单支付服务所以有可能返回回去给前端调用了
        return xcChooseCourseDto;
    }

    //获取学习的资格 如果改用户选的课程在我的课程表里面有记录 就代表有学习资格
    //学习的资格可以到我的课程表中去查询因为如果在我的课程表里面代表这门课是免费的或则是支付成功的
    //然后根据是否存在记录去判断是否存在资格 然后还需要判断到期的时间
    //学习资格，[{"code":"702001","desc":"正常学习"},{"code":"702002","desc":"没有选课或选课后没有支付"}
    // ,{"code":"702003","desc":"已过期需要申请续期或重新支付"}]
    @Override
    public XcCourseTablesDto getLearningStatus(String userId, Long courseId) {
        XcCourseTablesDto xcCourseTablesDto = new XcCourseTablesDto();
        //根据用户id和课程id查询我的课程表
        XcCourseTables xcCourseTables = getXcCourseTables(userId, courseId);
        if(xcCourseTables == null){
            xcCourseTablesDto.setLearnStatus("702002");
            return xcCourseTablesDto;
        }
        //判断到期的时间 判断过期时间getValidtimeEnd是否在如今时间之前 也就是如果在如今时间之前就表示过期 例如过期时间为28号 今天29号 那不就是过期了
        boolean before = xcCourseTables.getValidtimeEnd().isBefore(LocalDateTime.now());
        if(before){
            //过期
            xcCourseTablesDto.setLearnStatus("702003");
            BeanUtils.copyProperties(xcCourseTables,xcCourseTablesDto);
            return xcCourseTablesDto;
        }else{
            //没过期
            xcCourseTablesDto.setLearnStatus("702001");
            BeanUtils.copyProperties(xcCourseTables,xcCourseTablesDto);
            return xcCourseTablesDto;
        }

    }

    @Override
    @Transactional
    public boolean saveChooseCourseStauts(String chooseCourseId) {
        XcChooseCourse xcChooseCourse = xcChooseCourseMapper.selectById(chooseCourseId);
        if(xcChooseCourse == null){
            log.debug("接收购买课程的消息，根据选课id从数据库中找不到选课记录，选课记录id为：{}",chooseCourseId);
            return false;
        }
        String status = xcChooseCourse.getStatus();
        //如果是未支付才进行此操作 更新选课记录表的选课状态为已支付 然后先我的课程表插入一条记录
        if("701002".equals(status)){
            xcChooseCourse.setStatus("701001");
            //流程图中的更新选课记录表的状态 更新为选课成功 因为选课的状态只有在这个表有记录 我的课程表里面没有这个属性
            int i = xcChooseCourseMapper.updateById(xcChooseCourse);
            if(i<=0){
                XueChengPlusException.cast("添加选课记录失败");
            }
            //流程图中的更新选课记录表的状态后把这门课放到我的课程表中 这样用户就可以进行学习了
            XcCourseTables xcCourseTables = addCourseTabls(xcChooseCourse);
            return true;
        }

        return false;
    }

    @Override
    public PageResult<XcCourseTables> mycourestabls(MyCourseTableParams params) {
        String userId = params.getUserId();
        int page = params.getPage();
        int size = params.getSize();
        Page<XcCourseTables> xcCourseTablesPage = new Page<>(page,size);

        LambdaQueryWrapper<XcCourseTables> xcCourseTablesLambdaQueryWrapper = new LambdaQueryWrapper<XcCourseTables>()
                .eq(XcCourseTables::getUserId, userId);

        IPage<XcCourseTables> xcCourseTablesIPage = xcCourseTablesMapper.selectPage(xcCourseTablesPage,xcCourseTablesLambdaQueryWrapper);
        List<XcCourseTables> records = xcCourseTablesIPage.getRecords();
        long total = xcCourseTablesIPage.getTotal();
        PageResult<XcCourseTables> xcCourseTablesPageResult = new PageResult<XcCourseTables>(records,total,page,size);
        return xcCourseTablesPageResult;
    }

    //添加免费课程,免费课程加入选课记录表、我的课程表
    public XcChooseCourse addFreeCoruse(String userId, CoursePublish coursepublish) {
        Long courseId = coursepublish.getId();
        LambdaQueryWrapper<XcChooseCourse> xcChooseCourseLambdaQueryWrapper = new LambdaQueryWrapper<XcChooseCourse>()
                .eq(XcChooseCourse::getUserId, userId)
                .eq(XcChooseCourse::getCourseId, courseId)
                .eq(XcChooseCourse::getOrderType, "700001")//免费课程
                .eq(XcChooseCourse::getStatus, "701001");//选课成功
        //因为数据库表没有约束 可能存在多个相同数据 所以用selectList
        List<XcChooseCourse> xcChooseCourses = xcChooseCourseMapper.selectList(xcChooseCourseLambdaQueryWrapper);
        if (xcChooseCourses != null && xcChooseCourses.size()>0) {
            return xcChooseCourses.get(0);
        }
        //添加选课记录信息
        XcChooseCourse xcChooseCourse = new XcChooseCourse();
        xcChooseCourse.setCourseId(coursepublish.getId());
        xcChooseCourse.setCourseName(coursepublish.getName());
        xcChooseCourse.setCoursePrice(0f);//免费课程价格为0
        xcChooseCourse.setUserId(userId);
        xcChooseCourse.setCompanyId(coursepublish.getCompanyId());
        xcChooseCourse.setOrderType("700001");//免费课程
        xcChooseCourse.setCreateDate(LocalDateTime.now());
        xcChooseCourse.setStatus("701001");//选课成功
        xcChooseCourse.setValidDays(365);//免费课程默认365
        xcChooseCourse.setValidtimeStart(LocalDateTime.now());
        xcChooseCourse.setValidtimeEnd(LocalDateTime.now().plusDays(365));
        int insert = xcChooseCourseMapper.insert(xcChooseCourse);
        if(insert<=0){
            XueChengPlusException.cast("添加选课记录失败");
        }

        return xcChooseCourse;
    }
    //免费课程添加到我的课程表
    public XcCourseTables addCourseTabls(XcChooseCourse xcChooseCourse){
        //选课记录完成且未过期可以添加课程到课程表
        String status = xcChooseCourse.getStatus();
        if (!"701001".equals(status)){
            XueChengPlusException.cast("选课未成功，无法添加到课程表");
        }
        //查询我的课程表
        XcCourseTables xcCourseTables = getXcCourseTables(xcChooseCourse.getUserId(), xcChooseCourse.getCourseId());
        if(xcCourseTables!=null){
            return xcCourseTables;
        }
        XcCourseTables xcCourseTablesNew = new XcCourseTables();
        xcCourseTablesNew.setChooseCourseId(xcChooseCourse.getId());
        xcCourseTablesNew.setUserId(xcChooseCourse.getUserId());
        xcCourseTablesNew.setCourseId(xcChooseCourse.getCourseId());
        xcCourseTablesNew.setCompanyId(xcChooseCourse.getCompanyId());
        xcCourseTablesNew.setCourseName(xcChooseCourse.getCourseName());
        xcCourseTablesNew.setCreateDate(LocalDateTime.now());
        xcCourseTablesNew.setValidtimeStart(xcChooseCourse.getValidtimeStart());
        xcCourseTablesNew.setValidtimeEnd(xcChooseCourse.getValidtimeEnd());
        xcCourseTablesNew.setCourseType(xcChooseCourse.getOrderType());
        int insert = xcCourseTablesMapper.insert(xcCourseTablesNew);
        if(insert<=0){
            XueChengPlusException.cast("添加我的课程记录失败");
        }
        return xcCourseTablesNew;

    }
    //添加收费课程 收费课程只是加入选课记录表 还没有加入我的课程表
    public XcChooseCourse addChargeCoruse(String userId,CoursePublish coursepublish){


        LambdaQueryWrapper<XcChooseCourse> queryWrapper = new LambdaQueryWrapper<>();
        //拼接不能重复插入的条件为选课类型为收费 选课状态为待支付
        //是因为这个是收费课程在选课记录表的标识 如果不拼接全则会把其他课程混淆 也就是我现在要拼接出收费的课程 就必须把选课类型为收费拼接上去 不让会查到免费的课程
        //因为选课记录表里面既有收费的课程也有免费的课程的记录
        queryWrapper = queryWrapper.eq(XcChooseCourse::getUserId, userId)
                .eq(XcChooseCourse::getCourseId, coursepublish.getId())
                .eq(XcChooseCourse::getOrderType, "700002")//收费课程
                .eq(XcChooseCourse::getStatus, "701002");//待支付
        List<XcChooseCourse> xcChooseCourses = xcChooseCourseMapper.selectList(queryWrapper);
        if (xcChooseCourses != null && xcChooseCourses.size()>0) {
            //如果存在待支付交易记录直接返回
            return xcChooseCourses.get(0);
        }

        XcChooseCourse xcChooseCourse = new XcChooseCourse();
        xcChooseCourse.setCourseId(coursepublish.getId());
        xcChooseCourse.setCourseName(coursepublish.getName());
        xcChooseCourse.setCoursePrice(coursepublish.getPrice());
        xcChooseCourse.setUserId(userId);
        xcChooseCourse.setCompanyId(coursepublish.getCompanyId());
        xcChooseCourse.setOrderType("700002");//收费课程
        xcChooseCourse.setCreateDate(LocalDateTime.now());
        xcChooseCourse.setStatus("701002");//待支付

        xcChooseCourse.setValidDays(coursepublish.getValidDays());
        xcChooseCourse.setValidtimeStart(LocalDateTime.now());
        xcChooseCourse.setValidtimeEnd(LocalDateTime.now().plusDays(coursepublish.getValidDays()));
        int insert = xcChooseCourseMapper.insert(xcChooseCourse);
        if(insert<=0){
            XueChengPlusException.cast("添加选课记录失败");
        }
        return xcChooseCourse;
    }
    public XcCourseTables getXcCourseTables(String userId,Long courseId){
        XcCourseTables xcCourseTables = xcCourseTablesMapper.selectOne(new LambdaQueryWrapper<XcCourseTables>()
                .eq(XcCourseTables::getUserId, userId)
                .eq(XcCourseTables::getCourseId, courseId));
        return xcCourseTables;

    }
}
